#include "ImageDevice.hpp"
#include <iostream>
#include <boost/filesystem.hpp>

ImageDevice::ImageDevice() 
    : fileType_(FileType::INVALID), fileSize_(0), deviceState_(DeviceState::NOT_PRESENT) {
    // 初始化文件流
    fileStream_.exceptions(std::ifstream::failbit | std::ifstream::badbit);
}

ImageDevice::~ImageDevice() {
    if (fileStream_.is_open()) {
        fileStream_.close();
    }
    filePath_.clear();
}

size_t ImageDevice::GetFileSize() {
    if (fileStream_.is_open()) {
        fileStream_.seekg(0, std::ios::end);
        return fileStream_.tellg();
    }
    return -1;
}

void ImageDevice::SetFilePath(MountType type, const std::string& filePath) {
    FileType fileType = GetFileType(filePath);
    if (fileType == FileType::INVALID) {
        throw std::runtime_error("Invalid file path: " + filePath);
    }
    if (fileType != FileType::ISO_IMAGE && type == MountType::IsoImage) {
        throw std::runtime_error("Invalid file Type");
    }

    if (fileStream_.is_open()) {
        fileStream_.close();
    }

    // 打开文件流，使用二进制模式
    fileStream_.open(filePath, std::ios::in | std::ios::binary);
    if (!fileStream_.is_open()) {
        throw std::runtime_error("Failed to open file: " + filePath);
    }

    filePath_ = filePath; // 更新文件路径
    fileType_ = fileType; // 更新文件类型

    // 获取文件大小
    fileStream_.seekg(0, std::ios::end);
    fileSize_ = fileStream_.tellg();
    fileStream_.seekg(0, std::ios::beg);
}

int ImageDevice::ReadData(std::vector<uint8_t>& dataBuffer, size_t offset, size_t length) {
    // 检查偏移和长度是否有效
    if (offset >= fileSize_) {
        throw std::out_of_range("Offset is out of file bounds.");
    }
    if (offset + length > fileSize_) {
        length = fileSize_ - offset; // 调整长度以避免越界
    }

    // 移动文件指针到指定偏移
    fileStream_.seekg(offset, std::ios::beg);
    if (!fileStream_) {
        throw std::runtime_error("Failed to seek to offset: " + std::to_string(offset));
    }

    // 读取数据
    std::vector<uint8_t> buffer(length);
    fileStream_.read(reinterpret_cast<char*>(dataBuffer.data()), length);
    if (!fileStream_) {
        throw std::runtime_error("Failed to read data from file.");
    }

    return length;
}

DeviceState ImageDevice::TestUnitReady() {
    DeviceState curState = DeviceState::READY;

    if (filePath_.empty()) {
        SetDeviceState(DeviceState::NOT_PRESENT);
        return DeviceState::NOT_PRESENT;
    }

    DeviceState deviceState = GetDeviceState();
    if (fileSize_ <= 0) {
        if (deviceState == DeviceState::READY) {
            curState = DeviceState::MEDIUM_CHANGE;
        } else if (deviceState == DeviceState::MEDIUM_CHANGE ||
            deviceState == DeviceState::NOT_PRESENT) {
            curState = DeviceState::NOT_PRESENT;
        }
    } else {
        if (deviceState == DeviceState::NOT_PRESENT) {
            curState = DeviceState::MEDIUM_CHANGE;
        } else {
            curState = DeviceState::READY;
        }
    }

    SetDeviceState(curState); // 更新当前状态
    return curState;
}

